/*********************************************************************************
Class Name: NMRCreateUpdateOpptyfromContract
Author: Accenture IDC
Date:4/17/2012 
Requirement/Project Name: NMR  
Requirement Description:  Create or Update Opportunity for the incoming Contract
Version History: 0.2 Using ATTUID in lowercase
**********************************************************************************/
Public Class NMRCreateUpdateOpptyfromContract{
     /**
        method called in a trigger of Contract Summary Object to search for opportunity or 
        create new opportunity if not found
     **/
     
     public static Id nmrOpptyRecordTypeID = RecordTypeHelper.GetRecordTypeID('Opportunity', 'NMR Opportunity');
     public static Id NMRNotesRT = RecordTypeHelper.GetRecordTypeID('Notes__c', 'NMR Notes');
     
       
     Public static void createOppty(Map<string,Contract_Summary__c> contractMap, Map<string,Contract_Summary__c> opptyMap, Set<Id> accntIdSet){
         List<Opportunity> updateOpportunitylist = new List<Opportunity>();//Existing Opportunities that need to be updated with contract details
         List<Opportunity> createOpportunitylist = new List<Opportunity>();//New Opportunities that need to be created
         List<Notes__c> notesToAttach = new List<Notes__C>();//Notes to be attached to existing opportunities
         List<Notes__c> notesToCreate = new List<Notes__C>();//Notes to be attached to newly created Opportunities.
         Map<Id,Opportunity> opptytoCreateMap = new Map<Id,Opportunity>();//Opportunities to be created. 
         Map<Id,String> accountMap = new Map<Id,String>();//Account details for Account name and ownership details.
         Map<Id,Account> accountNameMap = selectAccount(accntIdSet);
         Set<id> accountidSet = new Set<Id>();
         Id NMRAccountRT = RecordTypeHelper.GetRecordTypeID('Account', 'CSS Customer');
         
     /***
     *
     * To update the contract on the existing Opportunity.
     *
     ***/
     if(opptyMap.size()>0){
         for(Opportunity oppty: [Select Id,OwnerId,Secondary_Owner__c, StageName,Amount, Disposition__c, CloseDate from Opportunity where Id in: opptyMap.KeySet()]){
            if(oppty.StageName != 'Stage 4 - Closed'){
                 oppty.Disposition__c = 'Closed - Approval';
                 oppty.CloseDate = Date.today();
                 oppty.Amount = opptyMap.get(oppty.Id).Contract_NISD_Amount__c;
                 updateOpportunitylist.add(oppty);                
            }
            else if(oppty.StageName == 'Stage 4 - Closed' && oppty.CloseDate == Date.Today()){
                if(oppty.Amount!=Null){
                     oppty.Amount = oppty.Amount + opptyMap.get(oppty.Id).Contract_NISD_Amount__c;
                }
                else{
                     oppty.Amount = opptyMap.get(oppty.Id).Contract_NISD_Amount__c;
                } 
                 updateOpportunitylist.add(oppty);                                
            }             
         }                     
         if(updateOpportunitylist.size()>0){
             try{
                 update updateOpportunitylist;
                 for(Opportunity opp: updateOpportunitylist){
                    Notes__c newNotes = new Notes__c();
                    newNotes.Type__c = 'Salesforce';
                    newNotes.Follow_Up__c = date.today();
                    newNotes.Opportunity_Disposition__c = 'Closed - Approval';
                    if(opp.Secondary_owner__c!=Null){
                        newNotes.OwnerId = opp.Secondary_owner__c;
                    }
                    else{
                        newNotes.OwnerId =  opp.OwnerId;
                    }                    
                    newNotes.Opportunity__c = opp.Id;
                    newNotes.RecordTypeid = NMRNotesRT;
                    notesToAttach.add(newNotes);
                 }
                 if(notesToAttach.size()>0){   
                     try{ 
                         insert notesToAttach;
                         }
                     catch(Exception exc){
                         system.debug(exc);
                     }
                 }
             }
             catch(DMLException e){
                 system.debug('Exception thrown while Update'+e);
             }             
         }
      }   
     /***
     *
     * To update the contract on a new Opportunity.
     *
     ***/ 
                   
         for(string cSummary: contractMap.KeySet()){
             if(contractMap.get(cSummary) != NULL){
                    Contract_Summary__c cont = new Contract_Summary__c();
                    cont = contractMap.get(cSummary);
                    Opportunity opp = new  Opportunity();
                    opp.Name = accountNameMap.get(cont.Account_Id__c).Name;
                    opp.AccountID = cont.Account_Id__c;
                    opp.StageName = 'Stage 4 - Closed';
                    opp.CloseDate = Date.Today();
                    if(cont.Contract_NISD_Amount__c!= Null){
                        opp.Amount = cont.Contract_NISD_Amount__c;
                    }
                    opp.Disposition__c = 'Closed - Approval';
                    opp.Customer_ID__c = cont.Customer_ID__c;
                    opp.RecordTypeId = nmrOpptyRecordTypeID;
                    opp.OwnerId = accountNameMap.get(cont.Account_Id__c).ownerid;
                    if(!NMRUtil.IsEmpty(accountNameMap.get(cont.Account_Id__c).OOR_Secondary_Account_Owner__c)){
                        opp.Secondary_owner__c = accountNameMap.get(cont.Account_Id__c).OOR_Secondary_Account_Owner__c;
                    }
                    createOpportunitylist.add(opp);
                    opptytoCreateMap.put(cont.Account_Id__c,opp);
             }
          }
             if(opptytoCreateMap.size()>0){
                 try{
                     insert opptytoCreateMap.values();
                     for(string contVar:contractMap.keySet()){
                         contractMap.get(contVar).Opportunity_Id__c = opptytoCreateMap.get(contractMap.get(contVar).Account_Id__c).Id;
                         //Create Notes 
                         Notes__c newNote = new Notes__c();
                            newNote.Type__c = 'Salesforce';
                            newNote.Follow_Up__c = date.today();
                            newNote.Opportunity_Disposition__c = 'Closed - Approval';
                            newNote.Opportunity__c = opptytoCreateMap.get(contractMap.get(contVar).Account_Id__c).Id;
                            
                            if(opptytoCreateMap.get(contractMap.get(contVar).Account_Id__c).Secondary_Owner__c != Null){ 
                                newNote.OwnerId =  opptytoCreateMap.get(contractMap.get(contVar).Account_Id__c).Secondary_Owner__c;
                            }
                            else{
                                newNote.OwnerId =  opptytoCreateMap.get(contractMap.get(contVar).Account_Id__c).OwnerId;
                            }
                            newNote.RecordTypeid = NMRNotesRT;
                            notesToCreate.add(newNote);                     
                     }
                     if(notesToCreate.size()>0){
                        try{ 
                            insert notesToCreate;
                         }
                        catch(Exception ex){
                            system.debug(ex);
                        }
                     }
                                         
                 }
                 catch(DMLException ex){
                     system.debug('Exception thrown while Insert'+ex);
                 }
           }                          
     }
     /***
     * Method to identify details of the Account
     ***/
     public static Map<Id,Account> selectAccount(Set<Id> accntSet){
     Map<Id,Account> accountMap = new Map<Id,Account>();
         for(Account acc:[Select id, name, OwnerId,OOR_Secondary_Account_Owner__c  from Account where Id in: accntSet]){
             accountMap.put(acc.Id,acc);
         }
         return accountMap;
     }
     
/************
*
*   Test class to check for creating new Oppty and attaching a contract to it
*
************/
    @isTest(SeeAllData=True)
    static void contractTest() {
    Id nmrOptyRecordTypeID = RecordTypeHelper.GetRecordTypeID('Opportunity', 'NMR Opportunity');
    Id nmrAccountRecordTypeID = RecordTypeHelper.GetRecordTypeID('Account', 'CSS Customer');
    
        List<Contract_Summary__c> csList = new list<Contract_Summary__c>();
        List<Proposal_Summary__c> psList = new list<Proposal_Summary__c>();
        List<Account> accList = new list<Account>();
        List<user> userList = new List<user>();
        
        profile profid = [Select Id from profile q where profile.Name ='NMR Sales'];
        User u2 = new User(alias = 'Opt22', email='sysadminOpty22@accenture.com',emailencodingkey='UTF-8', lastname='Test Opty 22', languagelocalekey='en_US',localesidkey='en_US', profileid = profid.id,timezonesidkey='America/Los_Angeles', username='testOppty22@testorg.com',SFA_Office__c='NYC',IsActive = True,css_office_name__c = 'NYC',ATTUID__c = 'AR2659');              
        insert u2;
        User u3 = new User(alias = 'Opt21', email='sysadminOpty21@accenture.com',emailencodingkey='UTF-8', lastname='Test Opty 21', languagelocalekey='en_US',localesidkey='en_US', profileid = profid.id,timezonesidkey='America/Los_Angeles', username='testOppty21@testorg.com',SFA_Office__c='NYC',IsActive = True,css_office_name__c = 'NYC',ATTUID__c = 'AR2658', ManagerId= u2.Id);              
        userList.add(u3);
        //userList.add(u2);
        insert userList;
        
        for(Integer i = 0; i < 200; i++){
        accList.add(new Account(Name = 'Acc' + i, Phone = '333'+i,CSS_CustomerID__c = '333'+i, RecordTypeID = nmrAccountRecordTypeID));
        }
        insert accList;
        for(Integer i = 0; i < 100; i++){
        psList.add(new Proposal_Summary__c(Proposal_Rep_ATTUID__c= 'AR2658',Customer_ID__c = '333'+i));
        }
        insert psList;
        for(Integer i = 100; i < 200; i++){
        csList.add(new Contract_Summary__c(Contract_Rep_ATTUID__c= 'AR2658',Account_Id__c = accList[i].id));
        }
        insert csList;
     }
/************
*
*   Test class to attach a contract to an existing Oppty.
*
************/     
     @isTest(SeeAllData=True)
     static void summaryTest(){
     Id nmrOptyRecordTypeID = RecordTypeHelper.GetRecordTypeID('Opportunity', 'NMR Opportunity');
     Id nmrAccountRecordTypeID = RecordTypeHelper.GetRecordTypeID('Account', 'CSS Customer');
     List<user> userList = new List<user>();
     
        profile profid = [Select Id from profile q where profile.Name ='NMR Sales'];
       /* User u3 = new User(alias = 'Opt21', email='sysadminOpty21@accenture.com',emailencodingkey='UTF-8', lastname='Test Opty 21', languagelocalekey='en_US',localesidkey='en_US', profileid = profid.id,timezonesidkey='America/Los_Angeles', username='testOppty21@testorg.com',SFA_Office__c='NYC',IsActive = True,css_office_name__c = 'NYC',ATTUID__c = 'aaa123');              
        insert u3;*/
        
        User u2 = new User(alias = 'Opt22', email='sysadminOpty22@accenture.com',emailencodingkey='UTF-8', lastname='Test Opty 22', languagelocalekey='en_US',localesidkey='en_US', profileid = profid.id,timezonesidkey='America/Los_Angeles', username='testOppty22@testorg.com',SFA_Office__c='NYC',IsActive = True,css_office_name__c = 'NYC',ATTUID__c = 'AR2650');              
        insert u2;
        User u3 = new User(alias = 'Opt21', email='sysadminOpty21@accenture.com',emailencodingkey='UTF-8', lastname='Test Opty 21', languagelocalekey='en_US',localesidkey='en_US', profileid = profid.id,timezonesidkey='America/Los_Angeles', username='testOppty21@testorg.com',SFA_Office__c='NYC',IsActive = True,css_office_name__c = 'NYC',ATTUID__c = 'AR2657', ManagerId= u2.Id);              
        userList.add(u3);
        //userList.add(u2);
        insert userList;
                
         Account acct = new Account();
         acct.Name = 'Test1';
         acct.OwnerId = u3.Id;
         acct.Phone = '9556665559';
         acct.CSS_CustomerID__c = '1';
         acct.RecordTypeID = nmrAccountRecordTypeID;
         insert acct;
         
         Opportunity oppty = new Opportunity();
         oppty.Name = 'Check';
         oppty.OwnerId = u2.Id;
         oppty.secondary_owner__c = u3.Id;
         oppty.AccountId = acct.Id; 
         oppty.StageName = 'Stage 1 - Proposal Created';  
         oppty.CloseDate = System.Today();
         oppty.RecordTypeId = nmrOptyRecordTypeID;
         insert oppty;
         
         Proposal_Summary__c psTest = new Proposal_Summary__c();
         psTest.Proposal_Rep_ATTUID__c = 'AR2657';
         psTest.Customer_ID__c = '1';
         //psTest.Name = 'TEST1';
         psTest.Proposal_NISD_Amount__c = 1000;
         insert psTest;
         
         oppty.Override_Amount__c = 1200;
         update oppty;
               
         Contract_Summary__c csTest = new Contract_Summary__c();
         csTest.Account_Id__c = acct.id;
         csTest.Opportunity_Id__c = oppty.id;   
         csTest.Contract_NISD_Amount__c = 1;
         //csTest.Name = 'TEST';
         insert csTest;        
        
     }           
}